
#include "netthread.h"

#include <QtGui>
#include <QtNetwork>

#define TCPIP_TIMEOUT 5000

//! [0]
NETThread::NETThread(int socketDescriptor, QObject *parent)
    : QThread(parent), socketDescriptor(socketDescriptor)
{
}
//! [0]

//! [1]
void NETThread::run()
{
    QTcpSocket tcpSocket;
//! [1] //! [2]
    if (!tcpSocket.setSocketDescriptor(socketDescriptor)) {
        emit error(tcpSocket.error());
        return;
    }

    memset(&doCommandData, 0, sizeof(cmd_t));
    memset(&sentCommandData, 0, sizeof(cmd_t));
    memset(&nextCommandData, 0, sizeof(cmd_t));

    doCommandData.command = CMD_RCV_CHECK_DEVICE;
    doCommandData.deviceID = m_deviceID;

    do{
        processCommand(&tcpSocket);
        memset(&doCommandData, 0, sizeof(cmd_t));
        if(nextCommandData.command != CMD_NONE)
        {
            memcpy(&doCommandData, &nextCommandData, sizeof(cmd_t));
            memset(&nextCommandData, 0, sizeof(cmd_t));
        }
    }while(doCommandData.command != CMD_NONE);

    tcpSocket.disconnectFromHost();
    tcpSocket.waitForDisconnected();
}

void NETThread::processCommand(QTcpSocket* tcpSocket)
{
    if(doCommandData.command == CMD_NONE)
        return;

    switch(doCommandData.command)
    {
        case CMD_RCV_CHECK_DEVICE:
        {
            const int Timeout = TCPIP_TIMEOUT;
            DataPackage dp;
            QByteArray inBlock;
            quint16 blockSize = SIZE_CHECK_DEVICEID_FRAME;
            RET_ERROR ret;

            while (tcpSocket->bytesAvailable() < blockSize){
                if (!tcpSocket->waitForReadyRead(Timeout)) {
                    return;
                }
            }

            inBlock = tcpSocket->readAll();

            ret = dp.parseCheckDEVICEID(inBlock);

            qDebug() << "parseCheckDEVICEID:" << ret;
            if(ret != ERROR_RECEIVE_INVALID_START)
            {
                nextCommandData.command = CMD_SEND_ACKNAK;
                nextCommandData.deviceID = m_deviceID;
                nextCommandData.frameNum = inBlock.data()[HEADER_FRAME_FRAMENO_POS]; //tcpInFrameNo;
                nextCommandData.acknakData.data = dp.convert2ACKNAKerror(ret);

                sentCommandData.command = doCommandData.command;
                sentCommandData.tryCnt = doCommandData.tryCnt;
            }
            break;
        }
        case CMD_SEND_ACKNAK:
        {
            DataPackage dp;
            QByteArray outBlock;

            if(true == dp.buildFrame(doCommandData, &outBlock))
            {
                int bytesToWrite = 0;
                bytesToWrite = (int)tcpSocket->write(outBlock);
            }
            if(doCommandData.acknakData.data)
            {
                if(sentCommandData.tryCnt++ <= 3)
                {
                    nextCommandData.command = CMD_RCV_CHECK_DEVICE;
                    nextCommandData.tryCnt = sentCommandData.tryCnt;
                    memset(&sentCommandData, 0, sizeof(cmd_t));
                }
            }
            break;
        }
        default:
            break;
    }
}

void NETThread::setDeviceID(quint16 deviceID)
{
    m_deviceID = deviceID;
}
